Skip to content

Forecast date picker (historical browse / season replay)#1126

Closed
busbyk wants to merge 2 commits into
native-forecast-reconcilefrom
forecast-date-picker
Closed

Forecast date picker (historical browse / season replay)#1126
busbyk wants to merge 2 commits into
native-forecast-reconcilefrom
forecast-date-picker

Conversation

@busbyk

@busbyk busbyk commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds a danger-colored calendar date picker to the native forecast page so readers can browse a zone's published forecast history ("season replay") and jump to any past forecast. Implements .scratch/native-product-pages/issues/09-forecast-date-picker.md.

Stacked PR. Base is native-forecast-reconcile (issue 01, #1121), which is not yet merged into native-product-pages. This PR's diff is only the date-picker work; it will auto-retarget to native-product-pages once #1121 lands. Do not merge before #1121.

Also rides along on this branch: a small docs-only commit (ADR 017 + DOMAIN_CONTEXT "Forecast Glossary" terms) capturing the forecast-glossary design decided separately — it belongs to issues 06/10, not the date picker, but was committed here with the author's okay.

Related Issues

Key Changes

  • New nested route forecasts/avalanche/[zone]/[date]/page.tsx (date=YYYY-MM-DD): on-demand server render, revalidate=2592000 (~immutable), dynamicParams=true, robots noindex.
  • Shared presentational NativeForecastView extracted from NativeForecastPage (warning optional — historical views pass null) so live + dated pages render identically.
  • Client ForecastDatePicker.client.tsx: shadcn Calendar (react-day-picker v9) in a Popover, days background-colored by danger_rating via dangerScale.ts; lazy-loads older months on demand.
  • Route handler GET /api/[center]/forecast-archive?zone&from&to{ dates: [{ date, productId, productType, dangerRating }] } for lazy month color loading; the page never ships the full archive.
  • Pure services/nac/archiveDates.ts (noon valid-date rule in center tz, dedupe-by-date latest-wins) + unit tests.
  • Nav via real Next <Link>s so the app's nextjs-toploader bar shows (it only triggers on anchor clicks, not router.push).

How to test

  1. pnpm dev, open a NWAC zone forecast (e.g. nwac.localhost:3000/forecasts/avalanche/west-slopes-north).
  2. Open the date picker — current month's days are danger-colored; page older months and colors lazy-load.
  3. Click a day → navigates to /[zone]/[date]; "Current forecast" returns to the live page; the toploader bar shows on navigation.
  4. Off-season: the picker anchors on the latest product's month (not today), so April forecasts are colored on open.
  5. pnpm test (archiveDates unit tests), at 375px + desktop.

Screenshots / Demo video

Verified live at 375px + desktop; calendar colors match the afp widget's April-2026 pattern. (Add a capture if helpful for review.)

Migration Explanation

None — all changes are read-path (NAC archive fetching + presentation). No Payload schema or DB migration. danger_rating was added to the zod product-list schema (API response shape), not a collection.

Future enhancements / Questions

busbyk and others added 2 commits June 22, 2026 13:44
Adds a danger-colored calendar date picker to the native single-zone
forecast page so readers can browse any past forecast/statement for the
zone. Default (no date) shows the current product; picking a date renders
that historical product at a shareable, server-rendered dated URL
(/forecasts/avalanche/[zone]/[date]). Implements issue 09.

Data layer
- Product list schema + archiveDates: noon valid-date rule (center tz),
  dedupe same-date products to the latest publish, carry danger_rating.
- fetchProductArchive narrows server-side via date_start/date_end (the
  params avy uses; type/zone_id are ignored), fetches uncached + trims to
  a small slice, then caches via unstable_cache (the full archive is ~13MB
  for NWAC, over Next's 2MB fetch-cache limit).
- fetchProductById for the historical product (immutable, long cache);
  kept view-only, not issue 02's adapter.
- GET /api/[center]/forecast-archive?zone&from&to for lazy month loading.

Pages
- New on-demand dated route [zone]/[date] (immutable ISR, noindex).
- Extracted shared NativeForecastView; live + dated pages compose it.
- Live page anchors the picker window on the current product's date (not
  today) so off-season the calendar opens populated on that month.

Picker (ForecastDatePicker.client)
- shadcn Calendar in a popover; days colored by danger_rating via the
  shared dangerColor scale, no-product days disabled, current/selected day
  outlined; calendar lazy-loads older months' colors on demand.
- Days, prev/next arrows, and "Current forecast" are real Next <Link>s so
  the global nextjs-toploader handles navigation feedback (its bar only
  starts on anchor clicks, not router.push).

Verified live at desktop + 375px; tsc/lint/test (541) pass.
ADR 017 records the native forecast-glossary design: a national shared
GlossaryTerms collection, client-side marking fed by a cache-tagged
/api/glossary endpoint (decoupled from the forecast page cache), no
per-center gate, and a definition popover with a "Learn more" link.

Adds the "Forecast Glossary" cluster (Glossary Term, Glossary tooltip)
to DOMAIN_CONTEXT.md and indexes 017 (plus back-filled 015/016) in the
decisions README. Re-acknowledges the CLAUDE.md->README drift binding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Preview deployment: https://forecast-date-picker.preview.avy-fx.org

@busbyk busbyk marked this pull request as draft July 1, 2026 21:30
@busbyk

busbyk commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Folded into #1129, which now targets native-product-pages and shows the full combined stack diff for single-PR review. Branch kept as a safety net.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant